/*******************************************************************************
 System Tasks File

  File Name:
    system_tasks.c

  Summary:
    This file contains source code necessary to maintain system's polled state
    machines.

  Description:
    This file contains source code necessary to maintain system's polled state
    machines.  It implements the "SYS_Tasks" function that calls the individual
    "Tasks" functions for all the MPLAB Harmony modules in the system.

  Remarks:
    This file requires access to the systemObjects global data structure that
    contains the object handles to all MPLAB Harmony module objects executing
    polled in the system.  These handles are passed into the individual module
    "Tasks" functions to identify the instance of the module to maintain.
 *******************************************************************************/

// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2013-2014 released Microchip Technology Inc.  All rights reserved.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).

You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
 *******************************************************************************/
// DOM-IGNORE-END


// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include <stdio.h>
#include "system_config.h"
#include "system_definitions.h"
#include "app.h"
#include "app1.h"
#include "app2.h"
#include "app3.h"
#include "app4.h"
#include "app5.h"
#include "pcf8575.h"
#include "user_config.h"
// *****************************************************************************
// *****************************************************************************
// Section: Local Prototypes
// *****************************************************************************
// *****************************************************************************

OS_TCB  _SYS_Tasks_TCB;
CPU_STK _SYS_TasksStk[512];

OS_TCB  _APP_Tasks_TCB;
CPU_STK _APP_TasksStk[512];

OS_TCB  _APP1_Tasks_TCB;
CPU_STK _APP1_TasksStk[512];

OS_TCB  _APP2_Tasks_TCB;
CPU_STK _APP2_TasksStk[512];

OS_TCB  _APP3_Tasks_TCB;
CPU_STK _APP3_TasksStk[512];

OS_TCB  _APP4_Tasks_TCB;
CPU_STK _APP4_TasksStk[512];

OS_TCB  _APP5_Tasks_TCB;
CPU_STK _APP5_TasksStk[512];


void _SYS_Tasks(void);      //系统检测线程
void _APP_Tasks(void);      //CAN总线通信
void _APP1_Tasks(void);     //DI输入
void _APP2_Tasks(void);     //AI输入
void _APP3_Tasks(void);     //DO
void _APP4_Tasks(void);     //AO
void _APP5_Tasks(void);     //RS-485

OS_TMR MyTmr00;
uint16_t dev_run_count = 0;

/*
 * ===  FUNCTION  ======================================================================
 *         Name:  timer_thread
 *  Description:
 * =====================================================================================
 */

void os_timer_thread(void *p_tmr, void *p_arg){

    dev_run_count ++;
    if(dev_run_count >= 60){        //统计设备运行时间
        dev_run_count = 0;
        dev_timer ++;
        mes_tbl[MES_OFS_DEV_TIME] = ((dev_timer >> 16) & 0x0000ffff);
        mes_tbl[MES_OFS_DEV_TIME + 1] = ((dev_timer >> 0) & 0x0000ffff);
    }

    if(cfg_tbl[CFG_OFS_AI1_HI_TIME] > 0){   //AI上限延时报警状态信息
        if(mes_tbl[MES_OFS_AI1_VALUE] > cfg_tbl[CFG_OFS_AI1_HI_ALARM]){

        }else{

        }
    }

    if(cfg_tbl[CFG_OFS_AI1_LO_TIME] > 0){   //AI下限延时报警状态信息

    }
    if(cfg_tbl[CFG_OFS_AI2_HI_TIME] > 0){   //A2上限延时报警状态信息

    }
    if(cfg_tbl[CFG_OFS_AI2_LO_TIME] > 0){   //A2下限延时报警状态信息

    }

	return ;
}		/* -----  end of function timer_thread  ----- */

// *****************************************************************************
// *****************************************************************************
// Section: System "Tasks" Routine
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void SYS_Tasks ( void )

  Remarks:
    See prototype in system/common/sys_module.h.
*/
void SYS_Tasks ( void )
{
    /* Maintain the state machines of all library modules executing polled in
    the system. */
    OS_ERR os_err;

    OSTaskCreate((OS_TCB      *)&_SYS_Tasks_TCB,
                (CPU_CHAR    *)"Sys Tasks",
                (OS_TASK_PTR  )_SYS_Tasks,
                (void        *)0,
                (OS_PRIO      )1,
                (CPU_STK     *)&_SYS_TasksStk[0],
                (CPU_STK_SIZE )0u,
                (CPU_STK_SIZE )512,
                (OS_MSG_QTY   )0u,
                (OS_TICK      )0u,
                (void        *)0,
                (OS_OPT       )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR      *)&os_err);

    /* Start multitasking (i.e. give control to RTOS). This function never returns */
    OSStart(&os_err);
}

void _SYS_Tasks(void)
{
    uint8_t ret;
    OS_ERR os_err;
//    CPU_STK_SIZE n_free;        //统计任务控制块堆栈使用
//    CPU_STK_SIZE n_used;        //统计任务控制块堆栈使用

    pcf8575_led_on(LED_ALL);
    OSTimeDly (500, OS_OPT_TIME_DLY, &os_err);
    pcf8575_led_off(LED_ALL);

    //OS_CFG_TMR_TASK_RATE_HZ = 10Hz 则第4个参数设置为10.则表示1S进一次os_timer_thread。
    OSTmrCreate(&MyTmr00, "timer", 0, 10, OS_OPT_TMR_PERIODIC, os_timer_thread, 0, &os_err);
    OSTmrStart(&MyTmr00, &os_err);

    /* Maintain the application's state machine. */
    OSTaskCreate((OS_TCB      *)&_APP_Tasks_TCB,
                (CPU_CHAR    *)"App Tasks",
                (OS_TASK_PTR  )_APP_Tasks,
                (void        *)0,
                (OS_PRIO      )1,
                (CPU_STK     *)&_APP_TasksStk[0],
                (CPU_STK_SIZE )0u,
                (CPU_STK_SIZE )512,
                (OS_MSG_QTY   )0u,
                (OS_TICK      )0u,
                (void        *)0,
                (OS_OPT       )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR      *)&os_err);
    OSTaskCreate((OS_TCB      *)&_APP1_Tasks_TCB,
                (CPU_CHAR    *)"App1 Tasks",
                (OS_TASK_PTR  )_APP1_Tasks,
                (void        *)0,
                (OS_PRIO      )2,
                (CPU_STK     *)&_APP1_TasksStk[0],
                (CPU_STK_SIZE )0u,
                (CPU_STK_SIZE )512,
                (OS_MSG_QTY   )0u,
                (OS_TICK      )0u,
                (void        *)0,
                (OS_OPT       )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR      *)&os_err);
    OSTaskCreate((OS_TCB      *)&_APP2_Tasks_TCB,
                (CPU_CHAR    *)"App2 Tasks",
                (OS_TASK_PTR  )_APP2_Tasks,
                (void        *)0,
                (OS_PRIO      )3,
                (CPU_STK     *)&_APP2_TasksStk[0],
                (CPU_STK_SIZE )0u,
                (CPU_STK_SIZE )512,
                (OS_MSG_QTY   )0u,
                (OS_TICK      )0u,
                (void        *)0,
                (OS_OPT       )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR      *)&os_err);
    OSTaskCreate((OS_TCB      *)&_APP3_Tasks_TCB,
                (CPU_CHAR    *)"App3 Tasks",
                (OS_TASK_PTR  )_APP3_Tasks,
                (void        *)0,
                (OS_PRIO      )4,
                (CPU_STK     *)&_APP3_TasksStk[0],
                (CPU_STK_SIZE )0u,
                (CPU_STK_SIZE )512,
                (OS_MSG_QTY   )0u,
                (OS_TICK      )0u,
                (void        *)0,
                (OS_OPT       )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR      *)&os_err);
    OSTaskCreate((OS_TCB      *)&_APP4_Tasks_TCB,
                (CPU_CHAR    *)"App4 Tasks",
                (OS_TASK_PTR  )_APP4_Tasks,
                (void        *)0,
                (OS_PRIO      )5,
                (CPU_STK     *)&_APP4_TasksStk[0],
                (CPU_STK_SIZE )0u,
                (CPU_STK_SIZE )512,
                (OS_MSG_QTY   )0u,
                (OS_TICK      )0u,
                (void        *)0,
                (OS_OPT       )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR      *)&os_err);
    OSTaskCreate((OS_TCB      *)&_APP5_Tasks_TCB,
                (CPU_CHAR    *)"App5 Tasks",
                (OS_TASK_PTR  )_APP5_Tasks,
                (void        *)0,
                (OS_PRIO      )6,
                (CPU_STK     *)&_APP5_TasksStk[0],
                (CPU_STK_SIZE )0u,
                (CPU_STK_SIZE )512,
                (OS_MSG_QTY   )0u,
                (OS_TICK      )0u,
                (void        *)0,
                (OS_OPT       )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                (OS_ERR      *)&os_err);

    while(1)
    {
	    //设备运行状态
	    mes_tbl[MES_OFS_DRV_STATE] |= 0X0001;

#if 1   //备用电源检测
	    ret = PLIB_PORTS_PinGet(PORTS_ID_0, PORT_CHANNEL_B, PORTS_BIT_POS_2);   //备点检测
	    if(ret == true){
		    pcf8575_led_off(LED_LO_02);
		    mes_tbl[MES_OFS_DRV_STATE] &= (~0X0010);
	    }else{
		    pcf8575_led_on(LED_LO_02);
		    mes_tbl[MES_OFS_DRV_STATE] |= 0X0010;
	    }
#endif

#if 1//单片机外部看门狗
	    PLIB_PORTS_PinToggle(PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_9);
#endif
	    pcf8575_led_on(LED_LO_01);
	    OSTimeDly (100, OS_OPT_TIME_DLY, &os_err);
	    pcf8575_led_off(LED_LO_01);
	    OSTimeDly (100, OS_OPT_TIME_DLY, &os_err);
	    pcf8575_led_on(LED_LO_01);
	    OSTimeDly (100, OS_OPT_TIME_DLY, &os_err);
	    pcf8575_led_off(LED_LO_01);
	    //		OSTimeDly (1000, OS_OPT_TIME_DLY, &os_err);
	    OSTimeDly (500, OS_OPT_TIME_DLY, &os_err);
#if 1//单片机外部看门狗
	    PLIB_PORTS_PinToggle(PORTS_ID_0, PORT_CHANNEL_G, PORTS_BIT_POS_9);
#endif

#if 1   //4~20mA保护继电器控制
	    if(cfg_tbl[CFG_OFS_AO_CHANNEL] == 0x00){
		    PLIB_PORTS_PinToggle(PORTS_ID_0, PORT_CHANNEL_D, PORTS_BIT_POS_6); //4~20mA保护
                    pcf8575_led_off(LED_HI_06);
            }else{
                    pcf8575_led_on(LED_HI_06);
            }
#endif
	    OSTimeDly (500, OS_OPT_TIME_DLY, &os_err);
//            PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//            printf("System Run OK!\r\n");
//            PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
#if 0   //各个线程控制块空间统计

	    OSTaskStkChk(&_SYS_Tasks_TCB, &n_free, &n_used, &os_err);
	    PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	    printf("SYS  free:%d used:%d\r\n", n_free, n_used);
	    PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);

	    OSTaskStkChk(&_APP_Tasks_TCB, &n_free, &n_used, &os_err);
	    PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	    printf("APP0 free:%d used:%d\r\n", n_free, n_used);
	    PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);

	    OSTaskStkChk(&_APP1_Tasks_TCB, &n_free, &n_used, &os_err);
	    PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	    printf("APP1 free:%d used:%d\r\n", n_free, n_used);
	    PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);

	    OSTaskStkChk(&_APP2_Tasks_TCB, &n_free, &n_used, &os_err);
	    PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	    printf("APP2 free:%d used:%d\r\n", n_free, n_used);
	    PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);

	    OSTaskStkChk(&_APP3_Tasks_TCB, &n_free, &n_used, &os_err);
	    PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	    printf("APP3 free:%d used:%d\r\n", n_free, n_used);
	    PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);

	    OSTaskStkChk(&_APP4_Tasks_TCB, &n_free, &n_used, &os_err);
	    PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	    printf("APP4 free:%d used:%d\r\n", n_free, n_used);
	    PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);

	    OSTaskStkChk(&_APP5_Tasks_TCB, &n_free, &n_used, &os_err);
	    PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	    printf("APP5 free:%d used:%d\r\n", n_free, n_used);
	    PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
#endif




	    /* Maintain system services */
	    /* Maintain the DEVCON system state machine. */
	    //    SYS_DEVCON_Tasks(sysObj.sysDevcon);
	    //
	    //    /* Maintain Device Drivers */
	    //        OSTimeDly (1000, OS_OPT_TIME_DLY, &os_err);
    }
}

void _APP_Tasks(void)
{
//    OS_ERR os_err;

    while(1)
    {
        APP_Tasks();
//        OSTimeDly (100, OS_OPT_TIME_DLY, &os_err);
    }
}
void _APP1_Tasks(void)
{
    OS_ERR os_err;

    while(1)
    {
        APP1_Tasks();
        OSTimeDly (10, OS_OPT_TIME_DLY, &os_err);
    }
}
void _APP2_Tasks(void)
{
    OS_ERR os_err;

    while(1)
    {
        APP2_Tasks();
        OSTimeDly (100, OS_OPT_TIME_DLY, &os_err);
    }
}
void _APP3_Tasks(void)
{
//    OS_ERR os_err;

    while(1)
    {
        APP3_Tasks();
//        OSTimeDly (100, OS_OPT_TIME_DLY, &os_err);
    }
}
void _APP4_Tasks(void)
{
//    OS_ERR os_err;

    while(1)
    {
        APP4_Tasks();
//        OSTimeDly (10000, OS_OPT_TIME_DLY, &os_err);
    }
}
void _APP5_Tasks(void)
{
//    OS_ERR os_err;

    while(1)
    {
        APP5_Tasks();
//        OSTimeDly (1000, OS_OPT_TIME_DLY, &os_err);
    }
}

_general_exception_handler(void){
        pcf8575_led_on(LED_LO_04);
        SoftReset();//软件复位
}
/*******************************************************************************
 End of File
 */

